# -*- coding: utf-8 -*-
import copy
import os
import time
import uuid

from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QMessageBox, QMenu, QAction, QDialog, QCheckBox, QTableWidgetItem, QAbstractItemView
from PyQt5.QtCore import Qt, QVariant
from docx import Document
from docx.enum.table import WD_TABLE_ALIGNMENT
from docx.oxml.ns import qn
from docx.shared import Pt, RGBColor

from component.TemplateSetting import Ui_Setting_Dialog
from component.Datasource import Datasource
from component.DBDialog import Ui_Dialog
import sqlite3
import pymysql
import psycopg2


# 判断字符是否为空
def isEmpty(obj):
    if obj is None or str.strip(obj) == "":
        return True


def showMessage(dialog_type, title, message):
    msg_box = QMessageBox(dialog_type, title, message)
    msg_box.exec_()


class Ui_MainWindow(object):
    datasources = []
    template = ['1', '1', '1', '1', '1', '1', '1', '1']
    title = ["编号", "字段名", "字段类型", "长度", "是否是主键", "是否为空", "默认值", "说明"]

    def setupUi(self, MainWindow):

        # 读取模板配置
        self.readTemplateConfig()

        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(933, 727)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap("ui/logo.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.splitter_2 = QtWidgets.QSplitter(self.centralwidget)
        self.splitter_2.setOrientation(QtCore.Qt.Vertical)
        self.splitter_2.setObjectName("splitter_2")
        self.splitter = QtWidgets.QSplitter(self.splitter_2)
        self.splitter.setOrientation(QtCore.Qt.Horizontal)
        self.splitter.setObjectName("splitter")
        self.treeWidget = QtWidgets.QTreeWidget(self.splitter)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(1)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.treeWidget.sizePolicy().hasHeightForWidth())
        self.treeWidget.setSizePolicy(sizePolicy)
        self.treeWidget.setObjectName("treeWidget")

        # 读取数据库显示已有的数据源
        self.getDatasources()
        for i in range(len(self.datasources)):
            root = QtWidgets.QTreeWidgetItem(self.treeWidget)
            brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
            root.setForeground(0, brush)
            # root.setCheckState(0, Qt.Unchecked)
        # 绑定双击事件
        self.treeWidget.itemDoubleClicked.connect(self.getTables)
        self.treeWidget.itemClicked.connect(self.getDoc)
        # 绑定右键菜单
        self.treeWidget.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeWidget.customContextMenuRequested.connect(self.treeWidgetItem_Right)
        # 绑定全选切换事件
        self.treeWidget.itemChanged.connect(self.handleChanged)

        self.tableWidget = QtWidgets.QTableWidget(self.splitter)
        self.tableWidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(2)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tableWidget.sizePolicy().hasHeightForWidth())
        self.tableWidget.setSizePolicy(sizePolicy)
        self.tableWidget.setObjectName("tableWidget")

        # 绘制预览表格
        self.drawTable()

        self.exportButton = QtWidgets.QPushButton(self.splitter_2)
        self.exportButton.setObjectName("exportButton")
        # 绑定导出事件
        self.exportButton.clicked.connect(self.exportDoc)

        self.verticalLayout.addWidget(self.splitter_2)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 933, 23))
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.MinimumExpanding, QtWidgets.QSizePolicy.Minimum)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.menubar.sizePolicy().hasHeightForWidth())
        self.menubar.setSizePolicy(sizePolicy)
        self.menubar.setObjectName("menubar")
        self.menu_new = QtWidgets.QMenu(self.menubar)
        self.menu_new.setObjectName("menu_new")
        self.menu_setting = QtWidgets.QMenu(self.menubar)
        self.menu_setting.setObjectName("menu_setting")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.actionmysql = QtWidgets.QAction(MainWindow)
        self.actionmysql.setObjectName("actionmysql")
        # 绑定弹窗事件
        self.actionmysql.triggered.connect(lambda: self.showDatasourceAddDialog("mysql"))
        self.actionpostgres = QtWidgets.QAction(MainWindow)
        self.actionpostgres.setObjectName("actionpostgres")
        # 绑定弹窗事件
        self.actionpostgres.triggered.connect(lambda: self.showDatasourceAddDialog("postgres"))

        self.actiontemplatesetting = QtWidgets.QAction(MainWindow)
        self.actiontemplatesetting.setObjectName("actiontemplatesetting")
        self.actiontemplatesetting.triggered.connect(self.showTemplateSettingDialog)

        self.actionreadme = QtWidgets.QAction(MainWindow)
        self.actionreadme.setObjectName("actionreadme")
        self.actionreadme.triggered.connect(self.readme)

        self.menu_new.addAction(self.actionmysql)
        self.menu_new.addAction(self.actionpostgres)
        self.menu_setting.addAction(self.actiontemplatesetting)
        self.menu_setting.addAction(self.actionreadme)
        self.menubar.addAction(self.menu_new.menuAction())
        self.menubar.addAction(self.menu_setting.menuAction())

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "DDETool_数据库设计文档导出工具"))
        self.treeWidget.headerItem().setText(0, _translate("MainWindow", "设计文档来源"))
        self.treeWidget.setColumnWidth(0, 200)
        self.treeWidget.setColumnWidth(1, 50)
        self.treeWidget.headerItem().setText(1, _translate("MainWindow", "类型"))
        __sortingEnabled = self.treeWidget.isSortingEnabled()
        self.treeWidget.setSortingEnabled(False)

        # 渲染数据
        for i in range(len(self.datasources)):
            self.treeWidget.topLevelItem(i).setText(0, _translate("MainWindow", self.datasources[i].name))
            self.treeWidget.topLevelItem(i).setText(1, _translate("MainWindow", self.datasources[i].dbtype))
        self.treeWidget.setSortingEnabled(__sortingEnabled)

        self.exportButton.setWhatsThis(
            _translate("MainWindow", "<html><head/><body><p>导出选中的表的数据库设计文档</p></body></html>"))
        self.exportButton.setText(_translate("MainWindow", "导出"))
        self.menu_new.setTitle(_translate("MainWindow", "新建"))
        self.menu_setting.setTitle(_translate("MainWindow", "设置"))
        self.actionmysql.setText(_translate("MainWindow", "mysql"))
        self.actionmysql.setStatusTip("添加一个mysql数据源")
        self.actionmysql.setToolTip(_translate("MainWindow", "mysql"))
        self.actionmysql.setShortcut(_translate("MainWindow", "Alt+M"))
        self.actionpostgres.setText(_translate("MainWindow", "postgres"))
        self.actionpostgres.setStatusTip("添加一个postgres数据源")
        self.actionpostgres.setShortcut(_translate("MainWindow", "Alt+P"))
        self.actiontemplatesetting.setText(_translate("MainWindow", "模板设置"))
        self.actionreadme.setText(_translate("MainWindow", "关于"))
        self.actiontemplatesetting.setShortcut(_translate("MainWindow", "Alt+T"))
        self.actiontemplatesetting.setStatusTip("设置数据库设计文档导出模板")

    # 获取设计文档信息
    def getColumnInfo(self, datasource, tables):

        data = []
        # sql脚本的名称就是数据库的名称
        with open("./data/" + datasource.dbtype + ".sql", 'r', encoding='utf8') as fp:
            r = fp.readline()
            sql = r
            line = 1
            while r != "":
                r = fp.readline()
                if line < len(self.template):
                    if self.template[line] == '1':
                        sql = sql + r
                    if line == len(self.template) - 1:
                        sql = sql[:-2] + ' '
                else:
                    sql = sql + r
                line += 1
        print(sql)
        # 根据数据库类型选择驱动
        if datasource.dbtype == 'mysql':
            operator = pymysql
        elif datasource.dbtype == 'postgres':
            operator = psycopg2
        # 建立连接
        conn = operator.connect(host=datasource.ip, port=datasource.port, user=datasource.username,
                                password=datasource.password,
                                database=datasource.database)
        cursor = conn.cursor()
        for table in tables:
            if datasource.dbtype == 'mysql':
                temp_sql = str.format(sql, table, datasource.database)
            else:
                temp_sql = str.format(sql, table, table)
        try:
            cursor.execute(temp_sql)
        except Exception as err:
            showMessage(QMessageBox.Critical, "错误", format(err))
            return data
        data.append(cursor.fetchall())
        cursor.close()
        conn.close()
        return data

    # 预览设计文档信息
    def getDoc(self, item, column):
        parent = item.parent()
        if parent is not None:
            index = self.treeWidget.indexOfTopLevelItem(parent)
            datasource = self.datasources[index]
        else:
            return ()
        # 连接获取结构信息
        tables = []
        tables.append(item.text(0))
        data = self.getColumnInfo(datasource, tables)
        if len(data) == 0:
            return
        # print(data[0])
        # 渲染表格
        row_count = self.tableWidget.rowCount()
        for i in range(row_count):
            self.tableWidget.removeRow(i)
        row_count = 0
        for row in data[0]:
            row_count += 1
            self.tableWidget.setRowCount(row_count)
            if self.template[0] == '1':
                table_item = QTableWidgetItem()
                table_item.setText(str(row_count))
                self.tableWidget.setItem(row_count - 1, 0, table_item)
            for i in range(len(row)):
                table_item = QTableWidgetItem()
                table_item.setText(str(row[i]))
                if self.template[0] == '1':
                    i = i + 1
                self.tableWidget.setItem(row_count - 1, i, table_item)

    # 绘制预览表格
    def drawTable(self):
        column_count = 0
        for checked in self.template:
            if checked == '1':
                column_count += 1
        self.tableWidget.setColumnCount(column_count)
        self.tableWidget.setRowCount(0)

        # title = ["编号", "字段名", "字段类型", "长度", "是否是主键", "是否为空", "默认值", "说明"]
        index = 0
        for i in range(len(self.template)):
            if self.template[i] == '1':
                item = QtWidgets.QTableWidgetItem()
                # item.setFlags(ItemFlag.)
                self.tableWidget.setHorizontalHeaderItem(index, item)
                index += 1
                item.setText(self.title[i])

    # 获取数据库树
    def getDatasources(self):
        # 保存到数据库中
        conn = sqlite3.connect('./data/data.db')
        c = conn.cursor()
        sql = "select id,name,ip,port,username,password,type,datasource from datasources"
        cursor = c.execute(sql)
        conn.commit()
        for row in cursor:
            datasource = Datasource(row[0], row[1], row[2], row[3], row[7], row[4], row[5], row[6])
            self.datasources.append(datasource)
        conn.close()

    # 获取表
    def getTables(self, item, index):
        if item.parent() is not None:
            return
        # 删除原有表节点
        item.takeChildren()
        _translate = QtCore.QCoreApplication.translate
        datasource = self.datasources[self.treeWidget.indexOfTopLevelItem(item)]
        dbtype = str.lower(datasource.dbtype)
        # 根据数据库类型，读取对应的设计文档sql脚本
        sql = ""
        if dbtype == 'mysql':
            operator = pymysql
            sql = "select table_name from information_schema.tables where table_schema='{}' and table_type='base table'"
            sql = str.format(sql, datasource.database)
        elif dbtype == 'postgres':
            operator = psycopg2
            sql = "select tablename from pg_tables where schemaname not like 'pg_%' and schemaname not like 'information_schema' and tableowner = '{}'"
            sql = str.format(sql, datasource.username)
        else:
            showMessage(QMessageBox.Critical, "错误", "该数据库类型暂不支持！")
            raise Exception("该数据库类型暂不支持！")
        try:

            conn = operator.connect(host=datasource.ip, port=datasource.port, user=datasource.username,
                                    password=datasource.password,
                                    database=datasource.database, connect_timeout=5)
        except BaseException as err:
            showMessage(QMessageBox.Warning, "警告", "数据库连接失败！原因：{0}".format(err))
            brush = QtGui.QBrush(QtGui.QColor(255, 0, 0))
            item.setForeground(0, brush)
            item.setData(0, Qt.CheckStateRole, QVariant())
            return ()
        else:
            cursor = conn.cursor()
            print(sql)
            cursor.execute(sql)
            tables = cursor.fetchall()
            cursor.close()
            conn.close()
            if len(tables) == 0:
                brush = QtGui.QBrush(QtGui.QColor(255, 255, 0))
                item.setForeground(0, brush)
                # 清除复选框
                item.setData(0, Qt.CheckStateRole, QVariant())
            else:
                brush = QtGui.QBrush(QtGui.QColor(0, 205, 0))
                item.setForeground(0, brush)
                item.setCheckState(0, Qt.Unchecked)
            for j in range(len(tables)):
                table_item = QtWidgets.QTreeWidgetItem(item)
                table_item.setText(0, _translate("MainWindow", str(tables[j][0])))
                table_item.setCheckState(0, Qt.Unchecked)
            item.setExpanded(True)

    # 右键事件功能函数
    def treeWidgetItem_Right(self, pos):
        item = self.treeWidget.currentItem()  # 获取当前节点
        if item.parent() is not None:
            return
        if item is not None:
            popMenu = QMenu()
            modify = QAction(u'编辑', self)
            modify.triggered.connect(self.editDatasourceItem)
            popMenu.addAction(modify)

            delete = QAction(u'删除', self)
            delete.triggered.connect(self.delDatasourceItem)
            popMenu.addAction(delete)

            popMenu.exec_(QCursor.pos())

    # 编辑数据库
    def editDatasourceItem(self):
        item = self.treeWidget.currentItem()
        item_index = self.treeWidget.indexOfTopLevelItem(item)
        datasource = self.datasources[item_index]
        dialog = QDialog()
        dialog_ui = Ui_Dialog()
        dialog_ui.setupUi(dialog)
        dialog_ui.le_USERNAME.setText(datasource.username)
        dialog_ui.le_Datasource.setText(datasource.database)
        dialog_ui.le_IP.setText(datasource.ip)
        dialog_ui.le_PORT.setText(str(datasource.port))
        dialog_ui.le_Name.setText(datasource.name)
        dialog_ui.le_PASSWORD.setText(datasource.password)
        # 确定按钮绑定添加事件
        dialog_ui.saveButton.clicked.connect(lambda: self.save(dialog, dialog_ui, datasource.dbtype, datasource.id))
        dialog_ui.cancelButton.clicked.connect(dialog.close)
        dialog.show()

    # 删除数据库
    def delDatasourceItem(self):
        item = self.treeWidget.currentItem()
        if item.parent() is not None:
            return
        datasource = self.datasources[self.treeWidget.indexOfTopLevelItem(item)]
        sql = "delete from datasources where id = '{}'"
        sql = str.format(sql, datasource.id)
        conn = sqlite3.connect('./data/data.db')
        c = conn.cursor()
        c.execute(sql)
        conn.commit()
        conn.close()
        item_index = self.treeWidget.indexOfTopLevelItem(item)
        del self.datasources[item_index]
        self.treeWidget.takeTopLevelItem(item_index)

    # 展示模板设置弹窗
    def showTemplateSettingDialog(self):
        dialog = QDialog()
        dialog_ui = Ui_Setting_Dialog()
        dialog_ui.setupUi(dialog)
        dialog_ui.saveButton.clicked.connect(lambda: self.saveTemplate(dialog_ui))
        # 读取配置文件
        self.readTemplateConfig()
        # 回显
        # print(template)
        children = dialog_ui.groupBox.children()
        for i in range(len(children)):
            if isinstance(children[i], QCheckBox):
                if self.template[i] == '1':
                    children[i].setChecked(True)
                else:
                    children[i].setChecked(False)
        dialog.exec()

    # 展示添加数据库弹窗
    def showDatasourceAddDialog(self, dbtype):
        dialog = QDialog()
        dialog_ui = Ui_Dialog()
        dialog_ui.setupUi(dialog)
        # 确定按钮绑定添加事件
        dialog_ui.saveButton.clicked.connect(lambda: self.save(dialog, dialog_ui, dbtype, None))
        dialog_ui.cancelButton.clicked.connect(dialog.close)
        dialog.exec()

    # 点击保存在数据库中添加一条记录
    def save(self, Dialog, dialog_ui, dbtype, id):
        _translate = QtCore.QCoreApplication.translate
        # 读取输入框中的数据
        name = dialog_ui.le_Name.text()
        ip = dialog_ui.le_IP.text()
        username = dialog_ui.le_USERNAME.text()
        port = int(dialog_ui.le_PORT.text())
        password = dialog_ui.le_PASSWORD.text()
        datasource = dialog_ui.le_Datasource.text()
        # 保存到数据库中
        conn = sqlite3.connect('./data/data.db')
        c = conn.cursor()
        if id is None:
            # 保存进内存
            id = uuid.uuid1()
            db = Datasource(id, name, ip, port, datasource, username, password, dbtype)
            self.datasources.append(db)
            # 添加一个树节点
            root = QtWidgets.QTreeWidgetItem(self.treeWidget)
            brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
            root.setForeground(0, brush)
            root.setText(0, _translate("MainWindow", name))
            root.setText(1, _translate("MainWindow", dbtype))
            sql = "insert into datasources (name,ip,port,username,password,type,datasource,id) values ('{}','{}',{},'{}','{}','{}','{}','{}')"
        else:
            db = Datasource(id, name, ip, port, datasource, username, password, dbtype)
            # 更新原来的数据库信息
            for index in range(len(self.datasources)):
                if self.datasources[index].id == id:
                    self.datasources[index] = db
                    # 修改树节点
                    item = self.treeWidget.topLevelItem(index)
                    brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
                    item.setForeground(0, brush)
                    item.setText(0, _translate("MainWindow", name))
                    item.takeChildren()
                    item.setData(0, Qt.CheckStateRole, QVariant())
                    break
            sql = "update datasources set name = '{}',ip = '{}',port = {},username = '{}',password = '{}',type ='{}',datasource = '{}' where id = '{}'"
        sql = str.format(sql, name, ip, port, username, password, dbtype, datasource, id)
        print(sql)
        c.execute(sql)
        conn.commit()
        conn.close()
        Dialog.close()

    # 全选功能实现
    def handleChanged(self, item, column):
        count = item.childCount()
        # print dir(item)
        if item.checkState(column) == Qt.Checked:
            # print "checked", item, item.text(column)
            for f in range(count):
                item.child(f).setCheckState(0, Qt.Checked)
        if item.checkState(column) == Qt.Unchecked:
            # print "unchecked", item, item.text(column)
            for f in range(count):
                item.child(f).setCheckState(0, Qt.Unchecked)

    # 保存模板
    def saveTemplate(self, dialog_ui):
        template_config = []
        children = dialog_ui.groupBox.children()
        for child in children:
            if isinstance(child, QCheckBox):
                if child.checkState():
                    template_config.append('1')
                else:
                    template_config.append('0')
        # 覆盖之前的配置
        self.template = template_config
        with open("./data/template.conf", mode='w+', encoding='utf-8') as f:
            template_str = ''.join(i for i in template_config)
            f.write(template_str)
        showMessage(QMessageBox.Warning, "提示", "设置保存成功！")
        # 重绘表格
        column_count = 0
        while column_count < self.tableWidget.columnCount():
            self.tableWidget.removeColumn(column_count)
            column_count += 1
        self.drawTable()

    # 读取模板配置文件
    def readTemplateConfig(self):
        try:
            with open("./data/template.conf", mode='r', encoding='utf-8') as f:
                self.template = list(f.readline())
        except FileNotFoundError:
            # template = ['1', '1', '1', '1', '1', '1', '1', '1']
            with open("./data/template.conf", mode='w+', encoding='utf-8') as f:
                template_str = ''.join(str(i) for i in self.template)
                f.write(template_str)

    # 导出设计文档
    def exportDoc(self):
        file = QtWidgets.QFileDialog.getSaveFileName(None, "保存设计文档", os.getcwd(), "数据库设计文档(*.docx)")
        if file[0] != '':
            output_datasource = []
            print(file)
            # 历遍树
            top_count = self.treeWidget.topLevelItemCount()
            for top in range(top_count):
                top_item = self.treeWidget.topLevelItem(top)
                child_count = top_item.childCount()
                if child_count != 0:
                    tables = []
                    for child in range(child_count):
                        child_item = top_item.child(child)
                        if child_item.checkState(0) == Qt.Checked:
                            table = child_item.text(0)
                            tables.append(table)
                    # 要导出的数据信息
                    if len(tables) > 0:
                        datasource = copy.copy(self.datasources[top])
                        datasource.tables = tables
                        output_datasource.append(datasource)
            # 生成文档
            word = Document()
            # 正文样式
            word.styles['Normal'].font.name = u'宋体'
            word.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
            word.styles['Normal'].font.size = Pt(10.5)
            word.styles['Normal'].font.color.rgb = RGBColor(0, 0, 0)
            date = time.strftime("%Y-%m-%d", time.localtime())
            # 标题
            head = word.add_heading("", 0)
            run = head.add_run("数据库设计文档 " + date)
            run.font.name = u'Cambria'
            run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
            run.font.color.rgb = RGBColor(0, 0, 0)
            for datasource in output_datasource:
                head = word.add_heading("", 1)
                run = head.add_run(str("数据库：" + datasource.name + '(' + datasource.database + ')'))
                run.font.name = u'Cambria'
                run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
                run.font.color.rgb = RGBColor(0, 0, 0)
                # 每个数据库中的表信息
                col = self.getColumnInfo(datasource, datasource.tables)
                print(col)
                # 统计表头个数
                head_count = 0
                title = []
                for i in range(len(self.template)):
                    if self.template[i] == '1':
                        title.append(self.title[i])
                        head_count += 1
                # 循环写出表格
                table_index = 0
                for col_info in col:
                    # 添加表题
                    table_title = datasource.tables[table_index]
                    head = word.add_heading("", 2)
                    run = head.add_run("表: " + table_title)
                    run.font.name = u'Cambria'
                    run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
                    run.font.color.rgb = RGBColor(0, 0, 0)
                    # 表
                    table_box = word.add_table(rows=len(col_info) + 1, cols=head_count)
                    table_box.style = 'Light Grid Accent 1'
                    row = 0
                    # 写入表头
                    hdr_cells = table_box.rows[row].cells
                    for i in range(len(title)):
                        hdr_cells[i].text = title[i]
                        # 设置居中 宽度自适应（貌似没效果）
                        hdr_cells[i].autofit = True
                        hdr_cells[i].paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
                    # 内容
                    for j in range(len(col_info)):
                        row += 1
                        row_cells = table_box.rows[row].cells
                        for k in range(len(col_info[j])):
                            x = k
                            # 需要插入编号
                            if self.template[0] == '1':
                                x += 1
                                row_cells[0].text = str(j + 1)
                            row_cells[x].text = str(col_info[j][k])
                            # 设置居中 宽度自适应（貌似没效果）
                            row_cells[x].autofit = True
                            row_cells[x].paragraphs[0].paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER
                    table_index += 1
            word.save(file[0])

    # 关于
    def readme(self):
        showMessage(QMessageBox.Information, "关于",
                    "作者：git@jasonchow1998\n项目地址：https://gitee.com/jasonchow1998/ddetool-gui.git")
